// define: 带参数的宏

#include <stdio.h>

#define cube(x) ((x) * (x) * (x))
// 错误定义的宏
#define RADTODEG1(x) (x * 57.29578)
#define RADTODEG2(x) (x) * 57.29578
// 带参数宏的宏的原则
// - 整个值都要有括号
// - 参数出现的每个地方都要有括号
#define RADTODEG3(x) ((x) * 57.29578)

// 可以带多个参数
#define MIN(a, b) ((a) > (b) ? (b) : (a))
// 也可以嵌套使用其他宏
// 定义宏的时候不要在结尾加分号!!!

// 宏: 牺牲空间(直接展开), 节省时间(调用函数)

// 宏的缺点: 没有类型检查
// 部分宏可以用 inline 替代

// 补充点东西
// #参数名 会被扩展为由实际参数带引号的字符串
// 不能加括号
#define testPrint(expr) printf(#expr" = %d\n", expr)

// ##: 连接实际参数
// 如果替换文本中的参数与 ## 相邻, 则该参数将被实际参数替换, \
// ## 与前后的空白将被删除, 并对替换后的结果重新扫描
// * 只是生成一个新标号
#define paste(front, back) front##back

#define createfun(name1, name2)\
void name1##name2()\
{\
    printf("the func is %s\n", __func__);\
}

int main(int argc, char const *argv[])
{
    int i;
    scanf("%d", &i);
    printf("%d\n", cube(i));

    printf("%d\n", RADTODEG1(5 + 2));
    printf("%d\n", 180 / RADTODEG2(1));

    // $ tail defineNote2.i
    // {
    //     int i;
    //     scanf("%d", &i);
    //     printf("%d\n", ((i) * (i) * (i)));

    //     printf("%d\n", (5 + 2 * 57.29578));
    //     printf("%d\n", 180 / (1) * 57.29578);

    //     return 0;
    // }

    testPrint(i + 1);

    int a, b, ab;
    a = b = 1;
    ab = 10;
    printf("%d\n", paste(a, b));

    createfun(test, Function);
    testFunction();
    
    return 0;
}